package com.site.blog.util;

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;

/**
 * @author : Connor-G 康纳-郭
 * @date : 18:02 21.1.14
 * @Company : http://www.zzrgsoft.org
 * @Version : 1.0
 */

@Slf4j
public class DbBackUtil {

    public static void main(String[] args) throws Exception {
        backup("127.0.0.1", "3306", "root", "root123", "D://", "ssm02.sql", "ssm02");
//        restore("D://ssm02.sql", "127.0.0.1", "3306", "root", "root123", "ssm02");
    }

    /**
     * 备份数据库
     *
     * @param host             host地址，可以是本机也可以是远程
     * @param userName         数据库用户名
     * @param password         数据库密码
     * @param backupFolderPath 备份路径
     * @param fileName         备份文件名
     * @param database         需要备份的数据库名称
     */
    public static boolean backup(String host, String port, String userName, String password, String backupFolderPath, String fileName,
                                 String database) throws Exception {

        File backupFolderFile = new File(backupFolderPath);
        if (!backupFolderFile.exists()) {
            // 如果目录不存在则创建文件
            backupFolderFile.mkdirs();
        }
        if (!backupFolderPath.endsWith(File.separator) && !backupFolderPath.endsWith("/")) {
            backupFolderPath = backupFolderPath + File.separator;
        }
        // 拼接执行命令
        String backupFilePath = backupFolderPath + fileName;
        StringBuilder sb = new StringBuilder();
        sb.append("mysqldump --opt ").append(" --add-drop-database ").append(" --add-drop-table ");
        sb.append(" -h").append(host).append(" -P").append(port).append(" -u").append(userName).append(" -p").append(password);
        sb.append(" --result-file=").append(backupFilePath).append(" --default-character-set=utf8 ").append(database);
        // 调用外部执行 exe 文件的 Java API
        log.info("=======================开始执行备份命令===========================");
        log.info(sb.toString());
        Process process = Runtime.getRuntime().exec(getCommand(sb.toString()));
        if (process.waitFor() == 0) {
            // 0 表示线程正常终止
            log.info("数据已经备份到 " + backupFilePath + " 文件中");
            return true;
        }
        return false;
    }

    /**
     * 还原数据库
     *
     * @param restoreFilePath 数据库备份的脚本路径
     * @param host            IP地址
     * @param userName        数据库用户名
     * @param password        数据库密码
     * @param database        数据库名称
     * @return
     * @throws Exception
     */
    public static boolean restore(String restoreFilePath, String host, String port, String userName, String password, String database)
            throws Exception {
        File restoreFile = new File(restoreFilePath);
        if (restoreFile.isDirectory()) {
            for (File file : restoreFile.listFiles()) {
                if (file.exists() && file.getPath().endsWith(".sql")) {
                    restoreFilePath = file.getAbsolutePath();
                    break;
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        sb.append("mysql -h").append(host).append(" -P").append(port).append(" -u").append(userName).append(" -p").append(password);
        sb.append(" ").append(database).append(" < ").append(restoreFilePath);
        try {
            log.info("=======================开始执行还原命令===========================");
            log.info(sb.toString());
            Process process = Runtime.getRuntime().exec(getCommand(sb.toString()));
            if (process.waitFor() == 0) {
                log.info("数据已从 " + restoreFilePath + " 导入到数据库中");
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.info("数据导入到数据库失败");
            return false;
        }
        return true;

    }

    /**
     * 执行命令
     *
     * @param command 需要执行的命令
     * @return
     */
    private static String[] getCommand(String command) {
        String os = System.getProperty("os.name");
        String shell = "/bin/bash";
        String c = "-c";
        if (os.toLowerCase().startsWith("win")) {
            log.info("当前操作系统为 " + os);
            shell = "cmd";
            c = "/c";
        }
        String[] cmd = {shell, c, command};
        return cmd;
    }
}
